﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Net;
using System.Net.Sockets;
using System.Text;
using System.Threading;
using TXK.CommonBase;

namespace TXK
{
	public class SiemensS7 : S7ScoketBase
	{
		private SimpleLock InteractiveLock = new SimpleLock();

		private byte[] S7_STOP = new byte[33]
		{
			3, 0, 0, 33, 2, 240, 128, 50, 1, 0,
			0, 14, 0, 0, 16, 0, 0, 41, 0, 0,
			0, 0, 0, 9, 80, 95, 80, 82, 79, 71,
			82, 65, 77
		};

		private byte[] S7_HOT_START = new byte[37]
		{
			3, 0, 0, 37, 2, 240, 128, 50, 1, 0,
			0, 12, 0, 0, 20, 0, 0, 40, 0, 0,
			0, 0, 0, 0, 253, 0, 0, 9, 80, 95,
			80, 82, 79, 71, 82, 65, 77
		};

		private byte[] S7_COLD_START = new byte[39]
		{
			3, 0, 0, 39, 2, 240, 128, 50, 1, 0,
			0, 15, 0, 0, 22, 0, 0, 40, 0, 0,
			0, 0, 0, 0, 253, 0, 2, 67, 32, 9,
			80, 95, 80, 82, 79, 71, 82, 65, 77
		};

		private const byte pduStart = 40;

		private const byte pduStop = 41;

		private const byte pduAlreadyStarted = 2;

		private const byte pduAlreadyStopped = 7;

		public short MaxPDUSize { get; set; } = 240;

		/// <summary>
		/// tcp连接超时参数
		/// </summary>
		public int ConnectTimeOut { get; set; } = 2000;

		/// <summary>
		/// tcp读取超时参数
		/// </summary>
		public int ReceiveTimeOut { get; set; } = 2000;


		private int SleepTime { get; set; } = 5;


		private int WaitTimes { get; set; } = 10;


		public bool Connect(string Ip, CpuType Cpu, int Rack, int Slot)
		{
			base.tcpclient = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);
			base.tcpclient.SetSocketOption(SocketOptionLevel.Socket, SocketOptionName.ReceiveTimeout, 2000);
			base.tcpclient.SetSocketOption(SocketOptionLevel.Socket, SocketOptionName.SendTimeout, 2000);
			IPEndPoint remoteEP;
			remoteEP = new IPEndPoint(IPAddress.Parse(Ip), 102);
			IAsyncResult asyncResult;
			asyncResult = base.tcpclient.BeginConnect(remoteEP, null, null);
			asyncResult.AsyncWaitHandle.WaitOne(this.ConnectTimeOut, exitContext: true);
			if (!asyncResult.IsCompleted)
			{
				base.tcpclient.Close();
				return false;
			}
			if (this.SendAndReceive(this.GetCOTPConnectionRequest(Cpu, Rack, Slot)) == null)
			{
				return false;
			}
			byte[] array;
			array = this.SendAndReceive(this.GetS7ConnectionSetup(Cpu));
			if (array == null)
			{
				return false;
			}
			if (array.Length == 27)
			{
				this.MaxPDUSize = (short)(array[25] * 256 + array[26]);
			}
			return true;
		}

		public void DisConnect()
		{
			if (base.tcpclient != null && base.tcpclient.Connected)
			{
				base.tcpclient.Close();
			}
		}

		private byte[] GetCOTPConnectionRequest(CpuType Cpu, int Rack, int Slot)
		{
			byte[] array;
			array = new byte[22]
			{
				3, 0, 0, 22, 17, 224, 0, 0, 0, 1,
				0, 192, 1, 10, 193, 2, 1, 2, 194, 2,
				1, 0
			};
			switch (Cpu)
			{
				case CpuType.S7200SMART:
					array[9] = 1;
					array[10] = 0;
					array[11] = 193;
					array[12] = 2;
					array[13] = 16;
					array[14] = 0;
					array[15] = 194;
					array[16] = 2;
					array[17] = 3;
					array[18] = 0;
					array[19] = 0;
					array[20] = 1;
					array[21] = 10;
					break;
				case CpuType.S7300:
					array[21] = 2;
					break;
				case CpuType.S7400:
					array[17] = 0;
					array[21] = (byte)(Rack * 32 + Slot);
					break;
				case CpuType.S71200:
					array[21] = 0;
					break;
				case CpuType.S71500:
					array[21] = 0;
					break;
			}
			return array;
		}

		private byte[] GetS7ConnectionSetup(CpuType Cpu)
		{
			byte[] array;
			array = new byte[25]
			{
				3, 0, 0, 25, 2, 240, 128, 50, 1, 0,
				0, 255, 255, 0, 8, 0, 0, 240, 0, 0,
				3, 0, 3, 7, 128
			};
			if (Cpu == CpuType.S7200SMART)
			{
				array[11] = 204;
				array[12] = 193;
				array[13] = 0;
				array[14] = 8;
				array[15] = 0;
				array[16] = 0;
				array[17] = 240;
				array[18] = 0;
				array[19] = 0;
				array[20] = 1;
				array[21] = 0;
				array[22] = 1;
				array[23] = 3;
				array[24] = 192;
			}
			return array;
		}

		/// <summary>
		/// 
		/// </summary>
		/// <param name="StoreType">西门子存储区</param>
		/// <param name="DB">DB号</param>
		/// <param name="StartByteAdr">开始地址</param>
		/// <param name="count">个数:这里没有大小限制,内部根据MaxPDUSize做了调整的</param>
		/// <returns></returns>
		public byte[] ReadBytes(StoreType StoreType, int DB, int StartByteAdr, int count)
		{
			this.InteractiveLock.Enter();
			try
			{
				List<byte> list;
				list = new List<byte>();
				int start;
				start = StartByteAdr;
				while (count > 0)
				{
					//单次最多读取字节数组
					int singlecount;
					 singlecount = Math.Min(count, this.MaxPDUSize - 18);
					byte[] array;
					array = this.ReadBytesWithSingleRequest(StoreType, DB, start, singlecount);
					if (array == null)
					{
						return list.ToArray();
					}
					list.AddRange(array);
					count -= singlecount;
					start += singlecount;
				}
				return (list.Count > 0) ? list.ToArray() : null;
			}
			catch (Exception)
			{
				return null;
			}
			finally
			{
				this.InteractiveLock.Leave();
			}
		}
		/// <summary>
		/// 
		/// </summary>
		/// <param name="StoreType">西门子存储区</param>
		/// <param name="DB">db号,如果不是DB区,可以随便填,内部都会转化为0</param>
		/// <param name="StartByteAdr">开始地址</param>
		/// <param name="count">个数</param>
		/// <returns>读取到的数据(字节数组)</returns>
		private byte[] ReadBytesWithSingleRequest(StoreType StoreType, int DB, int StartByteAdr, int count)
		{
			DB = ((StoreType == StoreType.DataBlock) ? DB : 0);
			byte[] array;
			array = new byte[count];
			try
			{
				int num;
				num = 31;
				ByteArray byteArray;
				byteArray = new ByteArray();
				//固定的
				byteArray.Add(new byte[3] { 3, 0, 0 });
				//后面的字节长度
				byteArray.Add((byte)num);
				//固定的
				byteArray.Add(new byte[18]
				{
					2, 240, 128, 50, 1, 0, 0, 0, 0, 0,
					14, 0, 0, 4, 1, 18, 10, 16
				});
				//表示存储区
				if ((uint)(StoreType - 28) <= 1u)
				{
					byteArray.Add((byte)StoreType);
                    //uint xx = 1u;
				}
				else
				{
					byteArray.Add(2);
				}
				//读取个数
				byteArray.Add(ByteArrayLib.GetByteArrayFromUShort((ushort)count));
				//db 号
				byteArray.Add(ByteArrayLib.GetByteArrayFromUShort((ushort)DB));
				//要读取的西门存储区
				byteArray.Add((byte)StoreType);
				//固定0
				byteArray.Add(0);
				//存储区不同而不同
				if ((uint)(StoreType - 28) <= 1u)
				{
					byteArray.Add(ByteArrayLib.GetByteArrayFromUShort((ushort)StartByteAdr));
				}
				else
				{
					byteArray.Add(ByteArrayLib.GetByteArrayFromUShort((ushort)(StartByteAdr * 8)));
				}
				byte[] array2;
				array2 = this.SendAndReceiveWithoutLock(byteArray.array);
				if (array2 == null)
				{
					throw new Exception("发送报文后,返回null");
				}
				if (array2[21] != byte.MaxValue)
				{
					throw new Exception("返回的第22个字节不等于255");
				}
				for (int i = 0; i < count; i++)
				{
					//第26个字节开始为我们需要的数据
					array[i] = array2[i + 25];
				}
				return array;
			}
			catch
			{
				return null;
			}
		}

		public object Read(StoreType StoreType, int DB, int StartByteAdr, VarType VarType, int VarCount)
		{
			switch (VarType)
			{
				case VarType.Byte:
					{
						int num;
						num = VarCount;
						if (num < 1)
						{
							num = 1;
						}
						byte[] array9;
						array9 = this.ReadBytes(StoreType, DB, StartByteAdr, num);
						if (array9 == null)
						{
							return null;
						}
						if (VarCount == 1)
						{
							return array9[0];
						}
						return array9;
					}
				case VarType.Word:
					{
						byte[] array4;
						array4 = this.ReadBytes(StoreType, DB, StartByteAdr, VarCount * 2);
						if (array4 == null)
						{
							return null;
						}
						if (VarCount == 1)
						{
							return UShortLib.GetUShortFromByteArray(array4);
						}
						return UShortLib.GetUShortArrayFromByteArray(array4);
					}
				case VarType.DWord:
					{
						byte[] array2;
						array2 = this.ReadBytes(StoreType, DB, StartByteAdr, VarCount * 4);
						if (array2 == null)
						{
							return null;
						}
						if (VarCount == 1)
						{
							return UIntLib.GetUIntFromByteArray(array2);
						}
						return UIntLib.GetUIntArrayFromByteArray(array2);
					}
				case VarType.Int:
					{
						byte[] array8;
						array8 = this.ReadBytes(StoreType, DB, StartByteAdr, VarCount * 2);
						if (array8 == null)
						{
							return null;
						}
						if (VarCount == 1)
						{
							return IntLib.GetIntFromByteArray(array8);
						}
						return IntLib.GetIntArrayFromByteArray(array8);
					}
				case VarType.DInt:
					{
						byte[] array5;
						array5 = this.ReadBytes(StoreType, DB, StartByteAdr, VarCount * 4);
						if (array5 == null)
						{
							return null;
						}
						if (VarCount == 1)
						{
							return IntLib.GetIntFromByteArray(array5);
						}
						return IntLib.GetIntArrayFromByteArray(array5);
					}
				case VarType.Real:
					{
						byte[] array7;
						array7 = this.ReadBytes(StoreType, DB, StartByteAdr, VarCount * 4);
						if (array7 == null)
						{
							return null;
						}
						if (VarCount == 1)
						{
							return FloatLib.GetFloatFromByteArray(array7);
						}
						return FloatLib.GetFloatArrayFromByteArray(array7);
					}
				case VarType.String:
					{
						byte[] array3;
						array3 = this.ReadBytes(StoreType, DB, StartByteAdr, VarCount);
						if (array3 == null)
						{
							return null;
						}
						return Encoding.ASCII.GetString(array3);
					}
				case VarType.Timer:
					{
						byte[] array6;
						array6 = this.ReadBytes(StoreType, DB, StartByteAdr, VarCount * 2);
						if (array6 == null)
						{
							return null;
						}
						if (VarCount == 1)
						{
							return Timers.FromByteArray(array6);
						}
						return Timers.ToArray(array6);
					}
				case VarType.Counter:
					{
						byte[] array;
						array = this.ReadBytes(StoreType, DB, StartByteAdr, VarCount * 2);
						if (array == null)
						{
							return null;
						}
						if (VarCount == 1)
						{
							return CounterLib.FromByteArray(array);
						}
						return CounterLib.ToArray(array);
					}
				default:
					return null;
			}
		}

		public object Read(string variable, VarType VarType)
		{
			string[] array;
			array = new string[8];
			string text;
			text = variable.ToUpper().Replace(" ", "");
			try
			{
				switch (text.Substring(0, 2))
				{
					case "DB":
						{
							string[] array2;
							array2 = text.Split('.');
							if (array2.Length < 2)
							{
								throw new Exception();
							}
							int dB;
							dB = int.Parse(array2[0].Substring(2));
							string text4;
							text4 = array2[1].Substring(0, 3);
							int num2;
							num2 = 0;
							int count;
							count = 0;
							if (array2[1].Contains('|'))
							{
								string[] array3;
								array3 = array2[1].Split('|');
								if (array3.Length != 2)
								{
									throw new Exception();
								}
								num2 = int.Parse(array3[0].Substring(3));
								count = int.Parse(array3[1]);
							}
							else
							{
								num2 = int.Parse(array2[1].Substring(3));
							}
							string text2;
							text2 = text4;
							if (text2 != null)
							{
								switch (text2)
								{
									case "DBB":
										return (byte)this.Read(StoreType.DataBlock, dB, num2, VarType.Byte, 1);
									case "DBW":
										if (VarType == VarType.Int)
										{
											return (short)this.Read(StoreType.DataBlock, dB, num2, VarType.Int, 1);
										}
										return (ushort)this.Read(StoreType.DataBlock, dB, num2, VarType.Word, 1);
									case "DBD":
										return VarType switch
										{
											VarType.Real => Convert.ToSingle(this.Read(StoreType.DataBlock, dB, num2, VarType.Real, 1)),
											VarType.DInt => Convert.ToInt32(this.Read(StoreType.DataBlock, dB, num2, VarType.DInt, 1)),
											_ => Convert.ToUInt32(this.Read(StoreType.DataBlock, dB, num2, VarType.DWord, 1)),
										};
									case "DBX":
										{
											int startByteAdr3;
											startByteAdr3 = num2;
											int num5;
											num5 = int.Parse(array2[2]);
											if (num5 > 7)
											{
												throw new Exception();
											}
											return BitLib.GetBitFromByte(Convert.ToByte(this.Read(StoreType.DataBlock, dB, startByteAdr3, VarType.Byte, 1)), num5);
										}
									case "DBS":
										{
											if (!text.Contains('|'))
											{
												int startByteAdr2;
												startByteAdr2 = num2;
												int num3;
												num3 = int.Parse(array2[2]);
												byte[] array4;
												array4 = this.ReadBytes(StoreType.DataBlock, dB, startByteAdr2, num3 + 2);
												if (array4 == null)
												{
													throw new Exception();
												}
												if (array4.Length != num3 + 2)
												{
													throw new Exception();
												}
												int num4;
												num4 = array4[1];
												if (num4 > 0)
												{
													return Encoding.GetEncoding("GBK").GetString(ByteArrayLib.GetByteArray(array4, 2, num4));
												}
												return "empty";
											}
											byte[] array5;
											array5 = this.ReadBytes(StoreType.DataBlock, dB, num2, count);
											if (array5 == null)
											{
												throw new Exception();
											}
											return StringLib.GetStringFromByteArray(array5, 0, array5.Length, Encoding.GetEncoding("GBK"));
										}
								}
							}
							throw new Exception();
						}
					case "IB":
						return (byte)this.Read(StoreType.Input, 0, int.Parse(text.Substring(2)), VarType.Byte, 1);
					case "IW":
						if (VarType == VarType.Int)
						{
							return (short)this.Read(StoreType.Input, 0, int.Parse(text.Substring(2)), VarType.Int, 1);
						}
						return (ushort)this.Read(StoreType.Input, 0, int.Parse(text.Substring(2)), VarType.Word, 1);
					case "ID":
						return VarType switch
						{
							VarType.Real => Convert.ToSingle(this.Read(StoreType.Input, 0, int.Parse(text.Substring(2)), VarType.Real, 1)),
							VarType.DInt => Convert.ToInt32(this.Read(StoreType.Input, 0, int.Parse(text.Substring(2)), VarType.DInt, 1)),
							_ => Convert.ToUInt32(this.Read(StoreType.Input, 0, int.Parse(text.Substring(2)), VarType.DWord, 1)),
						};
					case "QB":
						return (byte)this.Read(StoreType.Output, 0, int.Parse(text.Substring(2)), VarType.Byte, 1);
					case "QW":
						if (VarType == VarType.Int)
						{
							return (short)this.Read(StoreType.Output, 0, int.Parse(text.Substring(2)), VarType.Int, 1);
						}
						return (ushort)this.Read(StoreType.Output, 0, int.Parse(text.Substring(2)), VarType.Word, 1);
					case "QD":
						return VarType switch
						{
							VarType.Real => Convert.ToSingle(this.Read(StoreType.Output, 0, int.Parse(text.Substring(2)), VarType.Real, 1)),
							VarType.DInt => Convert.ToInt32(this.Read(StoreType.Output, 0, int.Parse(text.Substring(2)), VarType.DInt, 1)),
							_ => Convert.ToUInt32(this.Read(StoreType.Output, 0, int.Parse(text.Substring(2)), VarType.DWord, 1)),
						};
					case "MB":
						return (byte)this.Read(StoreType.Marker, 0, int.Parse(text.Substring(2)), VarType.Byte, 1);
					case "MW":
						if (VarType == VarType.Int)
						{
							return (short)this.Read(StoreType.Marker, 0, int.Parse(text.Substring(2)), VarType.Int, 1);
						}
						return (ushort)this.Read(StoreType.Marker, 0, int.Parse(text.Substring(2)), VarType.Word, 1);
					case "MD":
						return VarType switch
						{
							VarType.Real => Convert.ToSingle(this.Read(StoreType.Marker, 0, int.Parse(text.Substring(2)), VarType.Real, 1)),
							VarType.DInt => Convert.ToInt32(this.Read(StoreType.Marker, 0, int.Parse(text.Substring(2)), VarType.DInt, 1)),
							_ => Convert.ToUInt32(this.Read(StoreType.Marker, 0, int.Parse(text.Substring(2)), VarType.DWord, 1)),
						};
					default:
						{
							string text2;
							text2 = text.Substring(0, 1);
							if (text2 != null && new Dictionary<string, int>(8)
					{
						{ "E", 0 },
						{ "I", 1 },
						{ "A", 2 },
						{ "Q", 3 },
						{ "M", 4 },
						{ "T", 5 },
						{ "Z", 6 },
						{ "C", 7 }
					}.TryGetValue(text2, out var value))
							{
								StoreType storeType;
								string text3;
								int startByteAdr;
								int num;
								switch (value)
								{
									case 0:
									case 1:
										storeType = StoreType.Input;
										goto IL_09e7;
									case 2:
									case 3:
										storeType = StoreType.Output;
										goto IL_09e7;
									case 4:
										storeType = StoreType.Marker;
										goto IL_09e7;
									case 5:
										return (ushort)this.Read(StoreType.Timer, 0, int.Parse(text.Substring(1)), VarType.Timer, 1);
									case 6:
									case 7:
										{
											return (ushort)this.Read(StoreType.Counter, 0, int.Parse(text.Substring(1)), VarType.Counter, 1);
										}
									IL_09e7:
										text3 = text.Substring(1);
										if (text3.IndexOf(".") == -1)
										{
											throw new Exception();
										}
										startByteAdr = int.Parse(text3.Substring(0, text3.IndexOf(".")));
										num = int.Parse(text3.Substring(text3.IndexOf(".") + 1));
										if (num > 7)
										{
											throw new Exception();
										}
										return BitLib.GetBitFromByte(Convert.ToByte(this.Read(storeType, 0, startByteAdr, VarType.Byte, 1)), num);
								}
							}
							return null;
						}
				}
			}
			catch
			{
				return null;
			}
		}

		public bool WriteBytes(StoreType StoreType, int DB, int StartByteAdr, byte[] value)
		{
			this.InteractiveLock.Enter();
			try
			{
				int num;
				num = 0;
				int num2;
				num2 = value.Length;
				while (num2 > 0)
				{
					int num3;
					num3 = Math.Min(num2, 200);
					if (this.WriteBytesSingleRequest(StoreType, DB, StartByteAdr + num, value.Skip(num).Take(num3).ToArray()))
					{
						num2 -= num3;
						num += num3;
						continue;
					}
					return false;
				}
				return true;
			}
			catch (Exception)
			{
				return false;
			}
			finally
			{
				this.InteractiveLock.Leave();
			}
		}

		private bool WriteBytesSingleRequest(StoreType StoreType, int DB, int StartByteAdr, byte[] value)
		{
			byte[] array;
			array = new byte[512];
			try
			{
				int num;
				num = value.Length;
				int num2;
				num2 = 35 + value.Length;
				ByteArray byteArray;
				byteArray = new ByteArray();
				byteArray.Add(new byte[3] { 3, 0, 0 });
				byteArray.Add((byte)num2);
				byteArray.Add(new byte[7] { 2, 240, 128, 50, 1, 0, 0 });
				byteArray.Add(ByteArrayLib.GetByteArrayFromUShort((ushort)(num - 1)));
				byteArray.Add(new byte[2] { 0, 14 });
				byteArray.Add(ByteArrayLib.GetByteArrayFromUShort((ushort)(num + 4)));
				byteArray.Add(new byte[6] { 5, 1, 18, 10, 16, 2 });
				byteArray.Add(ByteArrayLib.GetByteArrayFromUShort((ushort)num));
				byteArray.Add(ByteArrayLib.GetByteArrayFromUShort((ushort)DB));
				byteArray.Add((byte)StoreType);
				byteArray.Add(0);
				byteArray.Add(ByteArrayLib.GetByteArrayFromUShort((ushort)(StartByteAdr * 8)));
				byteArray.Add(new byte[2] { 0, 4 });
				byteArray.Add(ByteArrayLib.GetByteArrayFromUShort((ushort)(num * 8)));
				byteArray.Add(value);
				array = this.SendAndReceiveWithoutLock(byteArray.array);
				if (array == null)
				{
					bool flag;
					flag = false;
				}
				if (array[21] != byte.MaxValue)
				{
					bool flag;
					flag = false;
				}
				return true;
			}
			catch (Exception)
			{
				return false;
			}
		}

		private bool WriteBit(StoreType dataType, int db, int startByteAdr, int bitAdr, bool value)
		{
			if (bitAdr < 0 || bitAdr > 7)
			{
				return false;
			}
			return this.WriteBitSingleRequest(dataType, db, startByteAdr, bitAdr, value);
		}

		private bool WriteBitSingleRequest(StoreType StoreType, int DB, int StartByteAdr, int bitAddress, bool bitValue)
		{
			byte[] array;
			array = new byte[512];
			byte[] array2;
			array2 = new byte[1] { (byte)(bitValue ? 1 : 0) };
			int num;
			num = array2.Length;
			int num2;
			num2 = 35 + array2.Length;
			ByteArray byteArray;
			byteArray = new ByteArray();
			byteArray.Add(new byte[3] { 3, 0, 0 });
			byteArray.Add((byte)num2);
			byteArray.Add(new byte[7] { 2, 240, 128, 50, 1, 0, 0 });
			byteArray.Add(ByteArrayLib.GetByteArrayFromUShort((ushort)(num - 1)));
			byteArray.Add(new byte[2] { 0, 14 });
			byteArray.Add(ByteArrayLib.GetByteArrayFromUShort((ushort)(num + 4)));
			byteArray.Add(new byte[6] { 5, 1, 18, 10, 16, 1 });
			byteArray.Add(ByteArrayLib.GetByteArrayFromUShort((ushort)num));
			byteArray.Add(ByteArrayLib.GetByteArrayFromUShort((ushort)DB));
			byteArray.Add((byte)StoreType);
			byteArray.Add(0);
			byteArray.Add(ByteArrayLib.GetByteArrayFromUShort((ushort)(StartByteAdr * 8 + bitAddress)));
			byteArray.Add(new byte[2] { 0, 3 });
			byteArray.Add(ByteArrayLib.GetByteArrayFromUShort((ushort)num));
			byteArray.Add(array2);
			array = this.SendAndReceive(byteArray.array);
			if (array == null)
			{
				throw new Exception();
			}
			if (array[21] != byte.MaxValue)
			{
				throw new Exception();
			}
			return true;
		}

		private bool Write(StoreType StoreType, int DB, int StartByteAdr, object value, int bitAdr = -1)
		{
			if (bitAdr == -1)
			{
				string name;
				name = value.GetType().Name;
				if (name != null && new Dictionary<string, int>(13)
				{
					{ "Byte", 0 },
					{ "Int16", 1 },
					{ "UInt16", 2 },
					{ "Int32", 3 },
					{ "UInt32", 4 },
					{ "Single", 5 },
					{ "Byte[]", 6 },
					{ "Int16[]", 7 },
					{ "UInt16[]", 8 },
					{ "Int32[]", 9 },
					{ "UInt32[]", 10 },
					{ "Single[]", 11 },
					{ "String", 12 },
					{ "Int64", 13 },
					{ "UInt64", 14 },
					{ "Double", 15 }
				}.TryGetValue(name, out var value2))
				{
					byte[] value3;
					switch (value2)
					{
						case 0:
							value3 = ByteArrayLib.GetByteArrayFromByte((byte)value);
							goto IL_029e;
						case 1:
							value3 = ByteArrayLib.GetByteArrayFromShort((short)value);
							goto IL_029e;
						case 2:
							value3 = ByteArrayLib.GetByteArrayFromUShort((ushort)value);
							goto IL_029e;
						case 3:
							value3 = ByteArrayLib.GetByteArrayFromInt((int)value);
							goto IL_029e;
						case 4:
							value3 = ByteArrayLib.GetByteArrayFromUInt((uint)value);
							goto IL_029e;
						case 5:
							value3 = ByteArrayLib.GetByteArrayFromFloat((float)value);
							goto IL_029e;
						case 6:
							value3 = (byte[])value;
							goto IL_029e;
						case 7:
							value3 = ByteArrayLib.GetByteArrayFromShortArray((short[])value);
							goto IL_029e;
						case 8:
							value3 = ByteArrayLib.GetByteArrayFromUShortArray((ushort[])value);
							goto IL_029e;
						case 9:
							value3 = ByteArrayLib.GetByteArrayFromIntArray((int[])value);
							goto IL_029e;
						case 10:
							value3 = ByteArrayLib.GetByteArrayFromUIntArray((uint[])value);
							goto IL_029e;
						case 11:
							value3 = ByteArrayLib.GetByteArrayFromFloatArray((float[])value);
							goto IL_029e;
						case 12:
							value3 = ByteArrayLib.GetByteArrayFromString((string)value, Encoding.GetEncoding("GBK"));
							goto IL_029e;
						case 13:
							value3 = ByteArrayLib.GetByteArrayFromLong((long)value);
							goto IL_029e;
						case 14:
							value3 = ByteArrayLib.GetByteArrayFromULong((ulong)value);
							goto IL_029e;
						case 15:
							{
								value3 = ByteArrayLib.GetByteArrayFromDouble((double)value);
								goto IL_029e;
							}
						IL_029e:
							return this.WriteBytes(StoreType, DB, StartByteAdr, value3);
					}
				}
				return false;
			}
			if (value is bool)
			{
				return this.WriteBit(StoreType, DB, StartByteAdr, bitAdr, (bool)value);
			}
			int num = default(int);
			int num2;
			if (value is int)
			{
				num = (int)value;
				num2 = 1;
			}
			else
			{
				num2 = 0;
			}
			if (num2 != 0)
			{
				if (bitAdr < 0 || bitAdr > 7)
				{
					return false;
				}
				return this.WriteBit(StoreType, DB, StartByteAdr, bitAdr, num == 1);
			}
			return false;
		}

		public bool Write(string variable, object value)
		{
			string text;
			text = variable.ToUpper().Replace(" ", "");
			try
			{
				switch (text.Substring(0, 2))
				{
					case "DB":
						{
							string[] array;
							array = text.Split('.');
							if (array.Length < 2)
							{
								throw new Exception();
							}
							int dB;
							dB = int.Parse(array[0].Substring(2));
							string text4;
							text4 = array[1].Substring(0, 3);
							int num;
							num = 0;
							string text5;
							text5 = array[1].Substring(3);
							num = (text5.Contains('|') ? int.Parse(text5.Split('|')[0]) : int.Parse(text5));
							string text2;
							text2 = text4;
							if (text2 != null)
							{
								switch (text2)
								{
									case "DBB":
										return this.Write(StoreType.DataBlock, dB, num, (byte)Convert.ChangeType(value, typeof(byte)));
									case "DBW":
										if (value is short)
										{
											return this.Write(StoreType.DataBlock, dB, num, (short)Convert.ChangeType(value, typeof(short)));
										}
										return this.Write(StoreType.DataBlock, dB, num, (ushort)Convert.ChangeType(value, typeof(ushort)));
									case "DBD":
										if (value is int)
										{
											return this.Write(StoreType.DataBlock, dB, num, (int)Convert.ChangeType(value, typeof(int)));
										}
										if (value is uint)
										{
											return this.Write(StoreType.DataBlock, dB, num, (uint)Convert.ChangeType(value, typeof(uint)));
										}
										return this.Write(StoreType.DataBlock, dB, num, (float)Convert.ChangeType(value, typeof(float)));
									case "DBR":
										if (value is long)
										{
											return this.Write(StoreType.DataBlock, dB, num, (long)Convert.ChangeType(value, typeof(long)));
										}
										if (value is ulong)
										{
											return this.Write(StoreType.DataBlock, dB, num, (ulong)Convert.ChangeType(value, typeof(ulong)));
										}
										return this.Write(StoreType.DataBlock, dB, num, (double)Convert.ChangeType(value, typeof(double)));
									case "DBS":
										if (!text5.Contains('|'))
										{
											byte[] byteArrayFromSiemensString;
											byteArrayFromSiemensString = ByteArrayLib.GetByteArrayFromSiemensString((string)value);
											byteArrayFromSiemensString[0] = byte.Parse(array[2]);
											return this.Write(StoreType.DataBlock, dB, num, byteArrayFromSiemensString);
										}
										return this.Write(StoreType.DataBlock, dB, num, ByteArrayLib.GetByteArrayFromString((string)value, Encoding.GetEncoding("GBK")));
									case "DBX":
										return this.Write(StoreType.DataBlock, dB, num, value, int.Parse(array[2]));
								}
							}
							return false;
						}
					case "IB":
						return this.Write(value: (byte)Convert.ChangeType(value, typeof(byte)), StoreType: StoreType.Input, DB: 0, StartByteAdr: int.Parse(text.Substring(2)));
					case "IW":
						return this.Write(value: (ushort)Convert.ChangeType(value, typeof(ushort)), StoreType: StoreType.Input, DB: 0, StartByteAdr: int.Parse(text.Substring(2)));
					case "ID":
						return this.Write(value: (uint)Convert.ChangeType(value, typeof(uint)), StoreType: StoreType.Input, DB: 0, StartByteAdr: int.Parse(text.Substring(2)));
					case "QB":
						return this.Write(value: (byte)Convert.ChangeType(value, typeof(byte)), StoreType: StoreType.Output, DB: 0, StartByteAdr: int.Parse(text.Substring(2)));
					case "QW":
						return this.Write(value: (ushort)Convert.ChangeType(value, typeof(ushort)), StoreType: StoreType.Output, DB: 0, StartByteAdr: int.Parse(text.Substring(2)));
					case "QD":
						return this.Write(value: (uint)Convert.ChangeType(value, typeof(uint)), StoreType: StoreType.Output, DB: 0, StartByteAdr: int.Parse(text.Substring(2)));
					case "MB":
						return this.Write(value: (byte)Convert.ChangeType(value, typeof(byte)), StoreType: StoreType.Marker, DB: 0, StartByteAdr: int.Parse(text.Substring(2)));
					case "MW":
						if (!(value is short))
						{
							return this.Write(value: (ushort)Convert.ChangeType(value, typeof(ushort)), StoreType: StoreType.Marker, DB: 0, StartByteAdr: int.Parse(text.Substring(2)));
						}
						return this.Write(value: (short)Convert.ChangeType(value, typeof(short)), StoreType: StoreType.Marker, DB: 0, StartByteAdr: int.Parse(text.Substring(2)));
					case "MD":
						if (!(value is int))
						{
							if (!(value is uint))
							{
								return this.Write(value: (float)Convert.ChangeType(value, typeof(float)), StoreType: StoreType.Marker, DB: 0, StartByteAdr: int.Parse(text.Substring(2)));
							}
							return this.Write(value: (uint)Convert.ChangeType(value, typeof(uint)), StoreType: StoreType.Marker, DB: 0, StartByteAdr: int.Parse(text.Substring(2)));
						}
						return this.Write(value: (int)Convert.ChangeType(value, typeof(int)), StoreType: StoreType.Marker, DB: 0, StartByteAdr: int.Parse(text.Substring(2)));
					default:
						{
							string text2;
							text2 = text.Substring(0, 1);
							if (text2 != null && new Dictionary<string, int>(8)
					{
						{ "E", 0 },
						{ "I", 1 },
						{ "A", 2 },
						{ "Q", 3 },
						{ "M", 4 },
						{ "T", 5 },
						{ "Z", 6 },
						{ "C", 7 }
					}.TryGetValue(text2, out var value2))
							{
								StoreType storeType;
								string text3;
								switch (value2)
								{
									case 0:
									case 1:
										storeType = StoreType.Input;
										goto IL_0a0c;
									case 2:
									case 3:
										storeType = StoreType.Output;
										goto IL_0a0c;
									case 4:
										storeType = StoreType.Marker;
										goto IL_0a0c;
									case 5:
										return this.Write(StoreType.Timer, 0, int.Parse(text.Substring(1)), (double)value);
									case 6:
									case 7:
										{
											return this.Write(StoreType.Counter, 0, int.Parse(text.Substring(1)), (short)value);
										}
									IL_0a0c:
										text3 = text.Substring(1);
										if (text3.IndexOf(".") == -1)
										{
											throw new Exception();
										}
										return this.Write(storeType, 0, int.Parse(text3.Substring(0, text3.IndexOf("."))), value, int.Parse(text3.Substring(text3.IndexOf(".") + 1)));
								}
							}
							throw new Exception();
						}
				}
			}
			catch
			{
				return false;
			}
		}

		public XktResult Write(string variable, string value, DataType dataType)
		{
			XktResult xktResult;
			xktResult = new XktResult();
			try
			{
				switch (dataType)
				{
					case DataType.Bool:
						xktResult.IsSuccess = this.Write(variable, value == "1" || value.ToLower() == "true");
						break;
					case DataType.Byte:
						xktResult.IsSuccess = this.Write(variable, byte.Parse(value));
						break;
					case DataType.Short:
						xktResult.IsSuccess = this.Write(variable, short.Parse(value));
						break;
					case DataType.UShort:
						xktResult.IsSuccess = this.Write(variable, ushort.Parse(value));
						break;
					case DataType.Int:
						xktResult.IsSuccess = this.Write(variable, int.Parse(value));
						break;
					case DataType.UInt:
						xktResult.IsSuccess = this.Write(variable, uint.Parse(value));
						break;
					case DataType.Float:
						xktResult.IsSuccess = this.Write(variable, float.Parse(value));
						break;
					case DataType.Double:
						xktResult.IsSuccess = this.Write(variable, double.Parse(value));
						break;
					case DataType.Long:
						xktResult.IsSuccess = this.Write(variable, long.Parse(value));
						break;
					case DataType.ULong:
						xktResult.IsSuccess = this.Write(variable, ulong.Parse(value));
						break;
					case DataType.String:
						xktResult.IsSuccess = this.Write(variable, value);
						break;
					case DataType.ByteArray:
						xktResult.IsSuccess = this.Write(variable, ByteArrayLib.GetByteArrayFromHexString(value));
						break;
					case DataType.HexString:
						xktResult.IsSuccess = false;
						xktResult.Message = "不支持的数据类型";
						break;
				}
			}
			catch (Exception ex)
			{
				xktResult.IsSuccess = false;
				xktResult.Message = ex.Message;
			}
			return xktResult;
		}

		public bool CoolStart()
		{
			byte[] array;
			array = this.SendAndReceive(this.S7_COLD_START);
			if (array != null)
			{
				if (array.Length >= 20)
				{
					if (array[19] == 40)
					{
						return true;
					}
					return false;
				}
				if (array.Length >= 21)
				{
					if (array[20] == 2)
					{
						return true;
					}
					return false;
				}
				return false;
			}
			return false;
		}

		public bool WarmStart()
		{
			byte[] array;
			array = this.SendAndReceive(this.S7_HOT_START);
			if (array != null)
			{
				if (array.Length >= 20)
				{
					if (array[19] == 40)
					{
						return true;
					}
					return false;
				}
				if (array.Length >= 21)
				{
					if (array[20] == 2)
					{
						return true;
					}
					return false;
				}
				return false;
			}
			return false;
		}

		public bool StopCPU()
		{
			byte[] array;
			array = this.SendAndReceive(this.S7_STOP);
			if (array != null)
			{
				if (array.Length == 19)
				{
					return true;
				}
				if (array.Length >= 20)
				{
					if (array[19] == 41)
					{
						return true;
					}
					return false;
				}
				if (array.Length >= 21)
				{
					if (array[20] == 7)
					{
						return true;
					}
					return false;
				}
				return false;
			}
			return false;
		}

		private byte[] SendAndReceive(byte[] SendByte)
		{
			//权限
			//if (!daddafdd.dasdsadsadsadsaddd(val: false))
			//{
			//	return null;
			//}
			this.InteractiveLock.Enter();
			try
			{
				INetMessage newNetMessage;
				newNetMessage = this.GetNewNetMessage();
				if (newNetMessage != null)
				{
					newNetMessage.SendBytes = SendByte;
				}
				base.tcpclient.Send(SendByte, SendByte.Length, SocketFlags.None);
				Thread.Sleep(1);
				XktResult<byte[]> xktResult;
				xktResult = base.ReceiveByMessage(base.tcpclient, this.ReceiveTimeOut, newNetMessage);
				if (!xktResult.IsSuccess)
				{
					return null;
				}
				if (newNetMessage != null && !newNetMessage.CheckHeadBytesLegal(base.Token.ToByteArray()))
				{
					return null;
				}
				return xktResult.Content;
			}
			catch (Exception)
			{
				return null;
			}
			finally
			{
				this.InteractiveLock.Leave();
			}
		}
		/// <summary>
		/// 发送报文后接受报文
		/// </summary>
		/// <param name="SendByte"></param>
		/// <returns></returns>
		private byte[] SendAndReceiveWithoutLock(byte[] SendByte)
		{
			try
			{
				INetMessage newNetMessage;
				newNetMessage = this.GetNewNetMessage();
				if (newNetMessage != null)
				{
					newNetMessage.SendBytes = SendByte;
				}
				base.tcpclient.Send(SendByte, SendByte.Length, SocketFlags.None);
				
				Thread.Sleep(1);
				XktResult<byte[]> xktResult;
				xktResult = base.ReceiveByMessage(base.tcpclient, this.ReceiveTimeOut, newNetMessage);
				if (!xktResult.IsSuccess)
				{
					return null;
				}
				if (newNetMessage != null && !newNetMessage.CheckHeadBytesLegal(base.Token.ToByteArray()))
				{
					return null;
				}
				return xktResult.Content;
			}
			catch (Exception)
			{
				return null;
			}
		}

		private INetMessage GetNewNetMessage()
		{
			return new S7Message();
		}

		public bool WriteMultipleVars(List<SiemensVar> SiemensVar)
		{
			if (SiemensVar.Count >= 20 || SiemensVar.Count <= 0)
			{
				return false;
			}
			List<SiemensGroup> list;
			list = new List<SiemensGroup>();
			foreach (SiemensVar item in SiemensVar)
			{
				SiemensGroup siemensGroup;
				siemensGroup = this.ConvertVarToGroup(item, IsRead: false);
				if (siemensGroup == null)
				{
					return false;
				}
				list.Add(siemensGroup);
			}
			return this.WriteMultipleVars(list);
		}

		public List<SiemensVar> ReadMultipleVars(List<SiemensVar> SiemensVar)
		{
			if (SiemensVar.Count >= 20 || SiemensVar.Count <= 0)
			{
				return null;
			}
			List<SiemensGroup> list;
			list = new List<SiemensGroup>();
			foreach (SiemensVar item in SiemensVar)
			{
				SiemensGroup siemensGroup;
				siemensGroup = this.ConvertVarToGroup(item);
				if (siemensGroup == null)
				{
					return null;
				}
				list.Add(siemensGroup);
			}
			list = this.ReadMultipleVars(list);
			if (list == null)
			{
				return null;
			}
			foreach (SiemensVar item2 in SiemensVar)
			{
				int index;
				index = SiemensVar.IndexOf(item2);
				if (list[index].Value == null)
				{
					return null;
				}
				if (list[index].Value.Length != this.GetReadByteLength(item2.VarAddress, item2.DataType))
				{
					return null;
				}
				switch (item2.DataType)
				{
					case DataType.Bool:
						item2.Value = BitLib.GetBitFromByte(offset: Convert.ToInt32(item2.VarAddress.Substring(item2.VarAddress.LastIndexOf(".") + 1)), b: list[index].Value[0]);
						break;
					case DataType.Byte:
						item2.Value = list[index].Value[0];
						break;
					case DataType.Short:
						item2.Value = ShortLib.GetShortFromByteArray(list[index].Value);
						break;
					case DataType.UShort:
						item2.Value = UShortLib.GetUShortFromByteArray(list[index].Value);
						break;
					case DataType.Int:
						item2.Value = IntLib.GetIntFromByteArray(list[index].Value);
						break;
					case DataType.UInt:
						item2.Value = UIntLib.GetUIntFromByteArray(list[index].Value);
						break;
					case DataType.Float:
						item2.Value = FloatLib.GetFloatFromByteArray(list[index].Value);
						break;
					case DataType.Double:
						item2.Value = DoubleLib.GetDoubleFromByteArray(list[index].Value);
						break;
					case DataType.Long:
						item2.Value = LongLib.GetLongFromByteArray(list[index].Value);
						break;
					case DataType.ULong:
						item2.Value = ULongLib.GetULongFromByteArray(list[index].Value);
						break;
					case DataType.String:
						if (!item2.VarAddress.Contains('|'))
						{
							byte[] value;
							value = list[index].Value;
							int num;
							num = value[1];
							if (num > 0)
							{
								item2.Value = Encoding.GetEncoding("GBK").GetString(ByteArrayLib.GetByteArray(value, 2, num));
							}
							else
							{
								item2.Value = "empty";
							}
						}
						else
						{
							item2.Value = StringLib.GetStringFromByteArray(list[index].Value, 0, list[index].Value.Length, Encoding.GetEncoding("GBK"));
						}
						break;
				}
			}
			return SiemensVar;
		}

		private SiemensGroup ConvertVarToGroup(SiemensVar var, bool IsRead = true)
		{
			SiemensGroup siemensGroup;
			siemensGroup = new SiemensGroup();
			try
			{
				if (!IsRead)
				{
					switch (var.DataType)
					{
						case DataType.Bool:
							return null;
						case DataType.Byte:
							siemensGroup.Value = ByteArrayLib.GetByteArrayFromByte(Convert.ToByte(var.DataType));
							break;
						case DataType.Short:
							siemensGroup.Value = ByteArrayLib.GetByteArrayFromShort(Convert.ToInt16(var.DataType));
							break;
						case DataType.UShort:
							siemensGroup.Value = ByteArrayLib.GetByteArrayFromUShort(Convert.ToUInt16(var.DataType));
							break;
						case DataType.Int:
							siemensGroup.Value = ByteArrayLib.GetByteArrayFromInt(Convert.ToInt32(var.DataType));
							break;
						case DataType.UInt:
							siemensGroup.Value = ByteArrayLib.GetByteArrayFromUInt(Convert.ToUInt32(var.DataType));
							break;
						case DataType.Float:
							siemensGroup.Value = ByteArrayLib.GetByteArrayFromFloat(Convert.ToSingle(var.DataType));
							break;
						case DataType.Double:
							siemensGroup.Value = ByteArrayLib.GetByteArrayFromDouble(Convert.ToDouble(var.DataType));
							break;
						case DataType.Long:
							siemensGroup.Value = ByteArrayLib.GetByteArrayFromLong(Convert.ToInt64(var.DataType));
							break;
						case DataType.ULong:
							siemensGroup.Value = ByteArrayLib.GetByteArrayFromULong(Convert.ToUInt64(var.DataType));
							break;
						case DataType.String:
							siemensGroup.Value = ByteArrayLib.GetByteArrayFromSiemensString(Convert.ToString(var.DataType));
							break;
						case DataType.ByteArray:
							siemensGroup.Value = (byte[])var.Value ;
							break;
					}
				}
				siemensGroup.Count = this.GetReadByteLength(var.VarAddress, var.DataType);
				string text;
				text = var.VarAddress.Replace(" ", "").ToUpper();
				switch (text.Substring(0, 2))
				{
					case "DB":
						{
							siemensGroup.StoreType = StoreType.DataBlock;
							string[] array;
							array = text.Split('.');
							if (array.Length < 2)
							{
								return null;
							}
							siemensGroup.DB = Convert.ToInt32(array[0].Substring(2));
							siemensGroup.StartByteAdr = Convert.ToInt32(array[1].Substring(3));
							break;
						}
					case "IB":
					case "IW":
					case "ID":
					case "EB":
					case "EW":
					case "ED":
						siemensGroup.StoreType = StoreType.Input;
						siemensGroup.StartByteAdr = Convert.ToInt32(text.Substring(2));
						break;
					case "QB":
					case "QW":
					case "QD":
					case "AB":
					case "AW":
					case "AD":
						siemensGroup.StoreType = StoreType.Output;
						siemensGroup.StartByteAdr = Convert.ToInt32(text.Substring(2));
						break;
					case "MB":
					case "MW":
					case "MD":
						siemensGroup.StoreType = StoreType.Marker;
						siemensGroup.StartByteAdr = Convert.ToInt32(text.Substring(2));
						break;
					default:
						switch (text.Substring(0, 1))
						{
							case "I":
							case "E":
								siemensGroup.StoreType = StoreType.Input;
								if (text.IndexOf(".") == -1)
								{
									return null;
								}
								siemensGroup.StartByteAdr = Convert.ToInt32(text.Substring(1).Substring(0, text.Substring(1).IndexOf(".")));
								break;
							case "Q":
							case "A":
								siemensGroup.StoreType = StoreType.Output;
								if (text.IndexOf(".") == -1)
								{
									return null;
								}
								siemensGroup.StartByteAdr = Convert.ToInt32(text.Substring(1).Substring(0, text.Substring(1).IndexOf(".")));
								break;
							case "M":
								siemensGroup.StoreType = StoreType.Marker;
								if (text.IndexOf(".") == -1)
								{
									return null;
								}
								siemensGroup.StartByteAdr = Convert.ToInt32(text.Substring(1).Substring(0, text.Substring(1).IndexOf(".")));
								break;
							case "C":
								siemensGroup.StoreType = StoreType.Counter;
								siemensGroup.StartByteAdr = Convert.ToInt32(text.Substring(1));
								break;
							case "T":
								siemensGroup.StoreType = StoreType.Timer;
								siemensGroup.StartByteAdr = Convert.ToInt32(text.Substring(1));
								break;
							default:
								return null;
						}
						break;
				}
			}
			catch (Exception)
			{
				return null;
			}
			return siemensGroup;
		}

		private int GetReadByteLength(string address, DataType dataType)
		{
			switch (dataType)
			{
				case DataType.Bool:
				case DataType.Byte:
					return 1;
				case DataType.Short:
				case DataType.UShort:
					return 2;
				case DataType.Int:
				case DataType.UInt:
				case DataType.Float:
					return 4;
				case DataType.String:
					if (address.Contains('|'))
					{
						string[] array;
						array = address.Split('|');
						if (array.Length == 2)
						{
							if (int.TryParse(array[1], out var result))
							{
								return result;
							}
							return -1;
						}
						return -1;
					}
					if (address.Contains('.'))
					{
						string[] array2;
						array2 = address.Split('.');
						if (array2.Length == 3)
						{
							if (int.TryParse(array2[2], out var result2))
							{
								return result2 + 2;
							}
							return -1;
						}
						return -1;
					}
					return -1;
				default:
					return -1;
			}
		}

		public List<SiemensGroup> ReadMultipleVars(List<SiemensGroup> SiemensGroup)
		{
			if (SiemensGroup.Sum((SiemensGroup dataItem) => dataItem.Count) > this.MaxPDUSize - 18)
			{
				if (SiemensGroup.Count != 1)
				{
					return null;
				}
				SiemensGroup[0].Value = this.ReadBytes(SiemensGroup[0].StoreType, SiemensGroup[0].DB, SiemensGroup[0].StartByteAdr, SiemensGroup[0].Count);
				return SiemensGroup;
			}
			if (SiemensGroup.Count >= ((this.MaxPDUSize == 240) ? 20 : 80))
			{
				return null;
			}
			int num;
			num = 19 + SiemensGroup.Count * 12;
			ByteArray byteArray;
			byteArray = new ByteArray();
			byteArray.Add(this.ReadHeaderPackage(SiemensGroup.Count).array);
			foreach (SiemensGroup item in SiemensGroup)
			{
				byteArray.Add(this.CreateReadDataRequestPackage(item.StoreType, item.DB, item.StartByteAdr, item.Count));
			}
			byte[] array;
			array = this.SendAndReceive(byteArray.array);
			if (array == null)
			{
				return null;
			}
			if (this.ParseDataIntoDataItems(array, SiemensGroup))
			{
				return SiemensGroup;
			}
			return null;
		}

		private bool ParseDataIntoDataItems(byte[] s7data, List<SiemensGroup> dataItems)
		{
			if (s7data.Length <= 21)
			{
				return false;
			}
			int num;
			num = 21;
			foreach (SiemensGroup dataItem in dataItems)
			{
				if (s7data[num] != byte.MaxValue)
				{
					return false;
				}
				num += 4;
				int count;
				count = dataItem.Count;
				dataItem.Value = s7data.Skip(num).Take(count).ToArray();
				num += count;
				if (dataItem.Count % 2 != 0)
				{
					num++;
				}
			}
			return true;
		}

		private ByteArray CreateReadDataRequestPackage(StoreType dataType, int db, int startByteAdr, int count = 1)
		{
			ByteArray byteArray;
			byteArray = new ByteArray();
			byteArray.Add(new byte[3] { 18, 10, 16 });
			if ((uint)(dataType - 28) <= 1u)
			{
				byteArray.Add((byte)dataType);
			}
			else
			{
				byteArray.Add(2);
			}
			byteArray.Add(ByteArrayLib.GetByteArrayFromUShort((ushort)count));
			byteArray.Add(ByteArrayLib.GetByteArrayFromUShort((ushort)db));
			byteArray.Add((byte)dataType);
			byteArray.Add((byte)((long)(startByteAdr * 8) / 65535L));
			if ((uint)(dataType - 28) <= 1u)
			{
				byteArray.Add(ByteArrayLib.GetByteArrayFromUShort((ushort)startByteAdr));
			}
			else
			{
				byteArray.Add(ByteArrayLib.GetByteArrayFromUShort((ushort)(startByteAdr * 8)));
			}
			return byteArray;
		}

		private ByteArray ReadHeaderPackage(int amount = 1)
		{
			ByteArray byteArray;
			byteArray = new ByteArray();
			byteArray.Add(new byte[2] { 3, 0 });
			byteArray.Add(ByteArrayLib.GetByteArrayFromShort((short)(19 + 12 * amount)));
			byteArray.Add(new byte[9] { 2, 240, 128, 50, 1, 0, 0, 0, 0 });
			byteArray.Add(ByteArrayLib.GetByteArrayFromUShort((ushort)(2 + amount * 12)));
			byteArray.Add(new byte[3] { 0, 0, 4 });
			byteArray.Add((byte)amount);
			return byteArray;
		}

		public bool WriteMultipleVars(List<SiemensGroup> SiemensGroup)
		{
			ByteArray byteArray;
			byteArray = new ByteArray();
			int num;
			num = this.CreateRequest(byteArray, SiemensGroup);
			byte[] array;
			array = this.SendAndReceive(byteArray.array);
			if (array == null)
			{
				return false;
			}
			if (this.ParseResponse(array, array.Length, SiemensGroup))
			{
				return true;
			}
			return false;
		}

		private int CreateRequest(ByteArray message, List<SiemensGroup> dataItems)
		{
			message.Add(Header.Template);
			message[18] = (byte)dataItems.Count;
			int num;
			num = dataItems.Count * Parameter.Template.Length;
			this.SetWordAt(message, 13, (ushort)(2 + num));
			int num2;
			num2 = Header.Template.Length;
			int num3;
			num3 = num2 + num;
			ByteArray byteArray;
			byteArray = new ByteArray();
			foreach (SiemensGroup dataItem in dataItems)
			{
				message.Add(Parameter.Template);
				byte[] value;
				value = dataItem.Value;
				message[num2 + 3] = (byte)2;
				this.SetWordAt(message, num2 + 4, (ushort)value.Length);
				this.SetWordAt(message, num2 + 6, (ushort)dataItem.DB);
				message[num2 + 8] = (byte)dataItem.StoreType;
				byteArray.Add(0);
				this.SetAddressAt(message, num2 + 9, dataItem.StartByteAdr, 0);
				int num4;
				num4 = value.Length;
				byteArray.Add(4);
				byteArray.AddWord((ushort)(num4 << 3));
				byteArray.Add(value);
				if ((num4 & 1) == 1)
				{
					byteArray.Add(0);
				}
				num2 += Parameter.Template.Length;
			}
			message.Add(byteArray.array);
			this.SetWordAt(message, 2, (ushort)message.Length);
			this.SetWordAt(message, 15, (ushort)(message.Length - num2));
			return message.Length;
		}

		private void SetAddressAt(ByteArray buffer, int index, int startByte, byte bitNumber)
		{
			int num;
			num = startByte * 8 + bitNumber;
			buffer[index + 2] = (byte)num;
			num >>= 8;
			buffer[index + 1] = (byte)num;
			buffer[index] = (byte)(num >> 8);
		}

		private void SetWordAt(ByteArray buffer, int index, ushort value)
		{
			buffer[index] = (byte)(value >> 8);
			buffer[index + 1] = (byte)value;
		}

		private bool ParseResponse(byte[] message, int length, List<SiemensGroup> dataItems)
		{
			if (length < 12)
			{
				return false;
			}
			if (this.GetWordAt(message, 10) != 0)
			{
				return false;
			}
			if (length < 14 + dataItems.Count)
			{
				return false;
			}
			IList<byte> list;
			list = new ArraySegment<byte>(message, 21, dataItems.Count);
			for (int i = 0; i < dataItems.Count; i++)
			{
				if (list[i] != byte.MaxValue)
				{
					return false;
				}
			}
			return true;
		}

		private ushort GetWordAt(IList<byte> buf, int index)
		{
			return (ushort)((buf[index] << 8) + buf[index]);
		}
	}
}
